001    /* $RCSfile: DES1KeySpec.java,v $
002     * $Revision: 1.10 $
003     * $Date: 2002/11/23 11:09:57 $
004     * $Author: uwe_guenther $
005     * $State: Exp $
006     *
007     * Created on August 11, 2001 11:18 AM
008     *
009     * Copyright (C) 2001 Uwe Guenther <uwe@cscc.de>
010     *
011     * This file is part of the jhbci JCE-ServiceProvider. The jhbci JCE-
012     * ServiceProvider is a library, written in JavaTM, that should be 
013     * used in HBCI banking applications (clients and may be servers),
014     * to do cryptographic operations.
015     *
016     * The jhbci library is free software; you can redistribute it and/or
017     * modify it under the terms of the GNU Lesser General Public
018     * License as published by the Free Software Foundation; either
019     * version 2.1 of the License, or (at your option) any later version.
020     *
021     * The jhbci library is distributed in the hope that it will be useful,
022     * but WITHOUT ANY WARRANTY; without even the implied warranty of
023     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
024     * Lesser General Public License for more details.
025     *
026     * You should have received a copy of the GNU Lesser General Public
027     * License along with this library; if not, write to the Free Software
028     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
029     *
030     */
031    
032    package de.cscc.crypto.provider.spec;
033    
034    import java.security.InvalidKeyException;
035    import java.util.Arrays;
036    
037    import de.cscc.crypto.util.ByteUtil;
038    
039    /** 
040     * DES secret key specification (56 bit or 64 bit with parity) class.
041     *
042     * <p>This class is immutable.
043     *
044     * @author  <a href=mailto:uwe@cscc.de>Uwe Günther</a>
045     * @version $Revision: 1.10 $
046     */
047    public class DES1KeySpec implements DESKeySpec, Cloneable {
048    
049        /** Key length in bytes. */    
050        private static final int DES_KEY_LEN = 8;
051        
052        /** The 4 DES weak keys. */    
053        private static final byte[][] WEAK_KEYS = {
054            //weak key 0
055            {
056                (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01, 
057                (byte)0x01, (byte)0x01, (byte)0x01, (byte)0x01
058            },
059            
060            //weak key 1
061            {
062                (byte)0xfe, (byte)0xfe, (byte)0xfe, (byte)0xfe, 
063                (byte)0xfe, (byte)0xfe, (byte)0xfe, (byte)0xfe
064            },
065            
066            //weak key 2
067            {
068                (byte)0x1f, (byte)0x1f, (byte)0x1f, (byte)0x1f, 
069                (byte)0x0e, (byte)0x0e, (byte)0x0e, (byte)0x0e
070            },
071            
072            //weak key 3
073            {
074                (byte)0xe0, (byte)0xe0, (byte)0xe0, (byte)0xe0, 
075                (byte)0xf1, (byte)0xf1, (byte)0xf1, (byte)0xf1         
076            }
077        };
078        
079        /** The 12 DES semi weak keys. */    
080        private static final byte[][] SEMI_WEAK_KEYS = {
081            //semi weak key 0
082            {
083                (byte)0x01, (byte)0xfe, (byte)0x01, (byte)0xfe, 
084                (byte)0x01, (byte)0xfe, (byte)0x01, (byte)0xfe
085            },
086            
087            //semi weak key 1
088            {
089                (byte)0xfe, (byte)0x01, (byte)0xfe, (byte)0x01, 
090                (byte)0xfe, (byte)0x01, (byte)0xfe, (byte)0x01
091            },
092            
093            //semi weak key 2
094            {
095                (byte)0x1f, (byte)0xe0, (byte)0x1f, (byte)0xe0, 
096                (byte)0x0e, (byte)0xf1, (byte)0x0e, (byte)0xf1
097            },
098            
099            //semi weak key 3
100            {
101                (byte)0xe0, (byte)0x1f, (byte)0xe0, (byte)0x1f, 
102                (byte)0xf1, (byte)0x0e, (byte)0xf1, (byte)0x0e
103            },
104            
105            //semi weak key 4
106            {
107                (byte)0x01, (byte)0xe0, (byte)0x01, (byte)0xe0, 
108                (byte)0x01, (byte)0xf1, (byte)0x01, (byte)0xf1
109            },
110            
111            //semi weak key 5
112            {
113                (byte)0xe0, (byte)0x01, (byte)0xe0, (byte)0x01, 
114                (byte)0xf1, (byte)0x01, (byte)0xf1, (byte)0x01
115            },
116            
117            //semi weak key 6
118            {
119                (byte)0x1f, (byte)0xfe, (byte)0x1f, (byte)0xfe, 
120                (byte)0x0e, (byte)0xfe, (byte)0x0e, (byte)0xfe
121            },
122            
123            //semi weak key 7
124            {
125                (byte)0xfe, (byte)0x1f, (byte)0xfe, (byte)0x1f, 
126                (byte)0xfe, (byte)0x0e, (byte)0xfe, (byte)0x0e
127            },
128            
129            //semi weak key 8
130            {
131                (byte)0x01, (byte)0x1f, (byte)0x01, (byte)0x1f, 
132                (byte)0x01, (byte)0x0e, (byte)0x01, (byte)0x0e
133            },
134            
135            //semi weak key 9
136            {
137                (byte)0x1f, (byte)0x01, (byte)0x1f, (byte)0x01, 
138                (byte)0x0e, (byte)0x01, (byte)0x0e, (byte)0x01
139            },
140            
141            //semi weak key 10
142            {
143                (byte)0xe0, (byte)0xfe, (byte)0xe0, (byte)0xfe, 
144                (byte)0xf1, (byte)0xfe, (byte)0xf1, (byte)0xfe
145            },
146            
147            //semi weak key 11
148            {
149                (byte)0xfe, (byte)0xe0, (byte)0xfe, (byte)0xe0, 
150                (byte)0xfe, (byte)0xf1, (byte)0xfe, (byte)0xf1
151            }
152            
153        };
154        
155        /** Internal data representation. */    
156        private byte[] key = new byte[8];    
157    
158        /** 
159         * Creates a new DES1KeySpec from a 16 bytes long byte array. We
160         * use the first 8 bytes in key as the key material for the DES key.
161         * The bytes that constitute the two DES keys are those between
162         * key[0] and key[8] inclusive.
163         *
164         * @param key the buffer with the DES keys.
165         * @throws InvalidKeyException if the given key material is shorter
166         *                              than 8 bytes or the key is weak or semi weak.
167         */
168        public DES1KeySpec(byte[] key) throws InvalidKeyException {
169            this(key, 0);
170        }    
171        
172        /**
173         * Creates a new DES1KeySpec from a 16 bytes long byte array.
174         *
175         * @param key the buffer with the DES keys.
176         * @param offset the offset in key, where the key starts.
177         * @throws InvalidKeyException if the given key material is shorter
178         *                              than 8 bytes or the key is weak or semi weak.
179         */
180        public DES1KeySpec(byte[] key, int offset) throws InvalidKeyException {
181            if(key.length-offset < 8){
182                throw new InvalidKeyException(
183                    "Usable byte range is " + (key.length-offset) + 
184                    " bytes large, but it should be 8 bytes or larger.");
185            }
186            
187            System.arraycopy(key, offset, this.key, 0, 8);
188            
189            //We have to first adjust the parity,
190            //because isWeak() and isSemiWeak() does deliver wrong results.
191            if (isParityAdjusted() == false){
192                adjustParity();
193            }
194            
195            //After parity adjusting, now we can test if the key is weak.
196            if (isWeak() == true){
197                throw new InvalidKeyException(
198                    "Key " + toString() + " is on of 4 weak DES keys.");
199            }
200            
201            //After parity adjusting, now we can test if the key is semi weak.
202            if (isSemiWeak() == true){
203                throw new InvalidKeyException(
204                    "Key " + toString() + " is on of 12 semi weak DES keys.");
205            }
206        }
207    
208        /**
209         * Creates a new DES1KeySpec from an existing one.
210         *
211         * @param key DesKeySpec object with a key.
212         */
213        public DES1KeySpec(DES1KeySpec key) {
214            System.arraycopy(key.key, 0, this.key, 0, 8);
215        } 
216        
217        /**
218         * Creates and returns a deep copy of this object.
219         *
220         * @return a clone of this instance.
221         * @see java.lang.Cloneable
222         * @exception CloneNotSupportedException if the object's class does not
223         *             support the <code>Cloneable</code> interface. Subclasses
224         *             that override the <code>clone</code> method can also
225         *             throw this exception to indicate that an instance cannot
226         *             be cloned.
227         */    
228        public Object clone() throws CloneNotSupportedException {
229            DES1KeySpec result = (DES1KeySpec) super.clone();
230            result.key = (byte[]) this.key.clone();
231            return result;
232        }
233        
234        /**
235         * Indicates whether some other object is "equal to" this one.
236         *
237         * @param   obj   the reference object with which to compare.
238         * @return  <code>true</code> if this object is the same as the obj
239         *         argument; <code>false</code> otherwise.
240         * @see     #hashCode()
241         * @see     java.util.Hashtable
242         */    
243        public boolean equals(Object obj) {
244             //Only for performance.
245            if (this == obj) {
246                return true;
247            }
248            
249            //If obj == null then instanceof returns false, see JLS 15.20.2
250            if (!(obj instanceof DES1KeySpec)) {            
251                return false;
252            }
253            
254            DES1KeySpec other = (DES1KeySpec)obj;
255            return Arrays.equals(this.key, other.key);
256        }
257    
258        /**
259         * Returns a hash code value for the object. This method is
260         * supported for the benefit of hashtables such as those provided by
261         * <code>java.util.Hashtable</code>.
262         *
263         * @return  a hash code value for this object.
264         * @see     #equals(java.lang.Object)
265         * @see     java.util.Hashtable
266         */    
267        public int hashCode() {
268            int result = 17;
269            for(int i = 0; i < this.key.length; i++) {
270                result = 37*result + this.key[i];
271            }
272            return result;
273        }        
274            
275        /**
276         * Returns a string representation of the object. 
277         *
278         * @return  a string representation of the object.
279         */    
280        public String toString() {
281            return ByteUtil.toHex(this.key);
282        }
283    
284        /**
285         * Resets the internal data representation to 0 (zero).
286         *
287         * Only for security reasons.
288         */    
289        private void reset() {
290            Arrays.fill(this.key, (byte) 0x00);
291        }
292        
293        /**
294         * Get the DES Key as byte[8].
295         *
296         * @return the DES Key as byte[8]. 
297         */
298        public byte[] getKey() { 
299            /*byte[] returnValue =new byte[8];
300            System.arraycopy(this.key, 0, returnValue, 0, 8);
301            return returnValue;*/
302            return (byte[]) this.key.clone();
303        }
304        
305        /**
306         * Checks parity for the whole key.
307         *
308         * @return true if the whole key is parity adjusted, respectively all 
309         *               bytes have odd parity, or false otherwise.
310         */
311        private boolean isParityAdjusted() {
312            for (int i = 0; i < this.key.length; i++) {
313                if (isParrityOdd(this.key[i]) == false) {
314                    
315                    //At least one byte int the key 
316                    //has even parity and is corrupted.
317                    return false; 
318                }
319            }
320            
321            //All bytes in the key has odd parity
322            //We say the key is parity adjusted.
323            return true;
324        }
325        
326        /**
327         * Checks parity of a byte.
328         *
329         * The right most bit used as placeholder to change the parity.
330         *
331         * 00000010 -> odd  parity
332         * 00000110 -> even parity
333         * 00001110 -> odd  parity
334         *   .
335         *   .
336         * 10001110 -> even parity
337         *
338         * @return true if the parity of byte b is odd, or false if the parity is even.
339         * @param b the byte to check.
340         */
341        private boolean isParrityOdd(byte b) {
342    
343            if (((
344                    (b >>> 0) ^
345                    (b >>> 1) ^ 
346                    (b >>> 2) ^ 
347                    (b >>> 3) ^ 
348                    (b >>> 4) ^ 
349                    (b >>> 5) ^ 
350                    (b >>> 6) ^ 
351                    (b >>> 7)
352                ) & 0x00000001 ) == 0x00000001)
353            {
354                return true;  //1
355            } else {
356                return false; //0    
357            }
358        }
359        
360        /**
361         * Adjust the parity to odd parity (means a odd sum of "1" bits).
362         *
363         * The right most bit (bit 8) in every byte in the DES key is the
364         * parity bit. Every byte in the DES key must have always odd parity!
365         * If one byte in the key has not odd parity, the key is corrupted.
366         */
367        private void adjustParity() {
368            for (int i = 0; i < 8; i++){
369                this.key[i] = oddParity(this.key[i]);
370            }
371        }
372    
373        /**
374         * Sets a byte b to odd parity, if it has even parity.
375         * If the input byte b has odd parity the return value will be
376         * the same as the input value b.
377         * 
378         * <pre>
379         * 00000010 -> odd  parity
380         * 00000110 -> even parity 
381         * 00001110 -> odd  parity
382         *    .
383         *    .
384         * 10001110 -> even parity
385         * </pre>
386         *
387         * Even parity means that the number of all "1" bits are even.
388         * Odd parity means that the number of all "1" bits are odd.
389         * 
390         * The algorithm works in the following way:
391         * The right most bit (bit 8) is the parity bit.
392         * Every byte in the DES key must have always odd parity!
393         * If one byte in the key has not odd parity, the key is corrupted.
394         *
395         * That means:
396         * Is the sum of all "1" bits from bit 1 to bit 7 odd, set bit 8 to "0".
397         * IS the sum of all "1" bits from bit 1 to bit 7 even, set bit 8 to "1".
398         *
399         * @param b the byte where will be set to odd parity.
400         * @return the parity adjusted byte.
401         */   
402        private byte oddParity(byte b) {    
403            return (byte)(
404                         (b & 0x000000fe) |     (           //set bit 8 to 0
405                                                    (
406                                                        (
407                                                            //xor bit 1 to 7
408                                                            (b >>> 1) ^ 
409                                                            (b >>> 2) ^ 
410                                                            (b >>> 3) ^ 
411                                                            (b >>> 4) ^ 
412                                                            (b >>> 5) ^ 
413                                                            (b >>> 6) ^ 
414                                                            (b >>> 7)
415                                                            
416                                                        //delete bit 1 to bit 7    
417                                                        ) & 0x00000001
418                                                        
419                                                    //if the xor result "0" means even
420                                                    //set party bit to "1" means odd
421                                                    //
422                                                    //if the xor result "1" means odd
423                                                    //set parity bit to "0" means odd                                                
424                                                    ) ^ 0x00000001 
425                                                )
426                          );
427        }
428           
429        /** 
430         * Returns true, if the internal data representation of the key is
431         * equal with one of the 4 weak keys.
432         *
433         * @return true if the key is weak, false otherwise.
434         */
435        private boolean isWeak() {   
436            for (int i = 0; i < 4; i++) {
437                if (Arrays.equals(DES1KeySpec.WEAK_KEYS[i], this.key)) {
438                    return true;
439                }
440            }
441            
442            return false;
443        }
444    
445        /**
446         * Returns true, if the internal data representation of the key is
447         * equal with one of the 12 semi weak keys.
448         *
449         * @return true if the key is semi weak, false otherwise.
450         */    
451        private boolean isSemiWeak() {        
452            for (int i = 0; i < 12; i++){
453                if (Arrays.equals(DES1KeySpec.SEMI_WEAK_KEYS[i], this.key)) {
454                    return true;
455                }
456            }
457            
458            return false;
459        }
460    }